import cantor
import random
import math

PARAMETER_ALPHABET = [1.2, 0.31, -0.31, -1.2]

PARAMETER_WORD_MAXLENGTH = 3
def _buildwords(alphabet, length):
    if length == 1:
        return [ [symbol] for symbol in alphabet]
    else:
        return [ [alphabet[0]] + word for word in _buildwords(alphabet[1:], length -1)]

PARAMETER_WORDS = _buildwords(PARAMETER_ALPHABET, PARAMETER_WORD_MAXLENGTH)


class FreeGrammar(object):
    def __init__(self, max_depth, alphabet):
        self.alphabet = alphabet
        self.max_depth = max_depth

    def generateWord(self, depth = None):
        seq = self.generate(depth)
        return "".join([self.alphabet[s] for s in seq])

    def generate(self, depth = None):
        if depth is None:
            depth = self.max_depth

        result = []
        for i in xrange(depth):
            result.append(random.randint(0, len(self.alphabet) -1))

        return result

class AbbaGrammar(FreeGrammar):
    def __init__(self, max_depth):
        self.alphabet = ['a', 'b']
        self.max_depth = max_depth

    def generate(self, depth = None):
        if depth is None:
            depth = self.max_depth
        a = random.randint(0,1)
        b = int(math.fabs(a-1))

        result = [a] + [b for i in xrange(self.max_depth-2)] + [a]

        return result[:depth]

class DistGrammar(AbbaGrammar):
    def __init__(self, max_depth, wordnumber=None, wordsize= None, words = None):
        AbbaGrammar.__init__(self, max_depth)
        g = lambda: random.randint(0, len(self.alphabet) -1)
        if words is None:
            words = [[g() for s in xrange(wordsize)] for n in xrange(wordnumber)]
        self.numwords = [[self.alphabet.index(w) for w in word] for word in words]

    def generate(self, depth = None):
        if depth is None:
            depth = self.max_depth
        result = []
        while len(result) < depth:
            result.extend(random.choice(self.numwords))

        return result[:depth]
